package com.transactional.service.differentclass;

import com.transactional.bean.User;
import com.transactional.dao.UserDao;
import com.transactional.service.innerclass.InnerService1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * @Deacription 演示类外部的调用
 * @Author baohuajie
 * @Date 2021/5/12 9:21
 * @Version 1.0
 **/
@Service
public class Service1 {

    @Autowired
    private UserDao userDao;
    @Autowired
    private Service2 service2;
    @Autowired
    private InnerService1 innerService1;

    @Transactional
    public int Service1Insert(User user){
        int i = userDao.insert(user);
        return i;
    }

    /**
     * Service1 demo1有@Transactional，Service2 demo1没有@Transactional（或者没有@Transactional）:
     * Service2 demo1 和 Service1 demo1 在同一个事物中执行
     * @param user
     * @return
     */
    @Transactional
    public int demo1(User user) {

        int aw = 0;

        int i = userDao.insert(user);
        user.setUserName(user.getUserName() + "Service1.demo1");
        int i1 = service2.demo1(user);
        return i + i1;
    }

    public int demo4(User user) {
        int i = userDao.insert(user);
        int ii = innerService1.demo4(user);
        return i;
    }

    /**
     * 多线程在事物中的表现:spring 的事物在线程之间不会传播，
     * userDao.insert(user)的事物id 5978779; 和 service2.multithreadDemo2的事物id5978784 没在同一个事物中
     * @param user
     * @return
     */
    @Transactional
    public int multithreadDemo1(User user) {
        int i = userDao.insert(user);
        new Thread(){
            @Override
            public void run() {
                service2.multithreadDemo2(user);
            }
        }.start();

        return 0;
    }


    /**
     * Spring 事务提交之后再执行操作
     *
     * @param user
     * @return
     */
    @Transactional
    public int afterCommitDemo1(User user) {
        int i = userDao.insert(user);
        TransactionSynchronizationManager.registerSynchronization(new MyTransactionSynchronizationAdapter(user));
        return 0;
    }

    class MyTransactionSynchronizationAdapter extends TransactionSynchronizationAdapter{

        private User user;

        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        public MyTransactionSynchronizationAdapter(User user) {
            this.user = user;
        }

        @Override
        public void afterCommit() {
            // service2.afterCommitDemo1 虽然有@Transactional，但是异常时不会回滚
            service2.afterCommitDemo1(user);
        }
    }




}
